package com.fh.modules.dbms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fh.common.exception.Assert;
import com.fh.common.web.impl.AbstractServiceImpl;
import com.fh.db.DbSource;
import com.fh.db.SqlRunner;
import com.fh.modules.dbms.entity.DbmsDbsource;
import com.fh.modules.dbms.entity.DbmsDbtype;
import com.fh.modules.dbms.entity.DbmsView;
import com.fh.modules.dbms.mapper.DbmsViewMapper;
import com.fh.modules.dbms.model.CompareResultModel;
import com.fh.modules.dbms.service.IDbmsDbsourceService;
import com.fh.modules.dbms.service.IDbmsDbtypeService;
import com.fh.modules.dbms.service.IDbmsViewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @Author qiujunda
 * @Date 14/07/2020
 * @Description
 */
@Service
public class DbmsViewServiceImpl extends AbstractServiceImpl<DbmsViewMapper, DbmsView> implements IDbmsViewService {

    @Autowired
    private DbmsViewMapper dbmsViewMapper;
    @Autowired
    private IDbmsDbsourceService dbmsDbsourceService;
    @Autowired
    private IDbmsDbtypeService dbmsDbtypeService;

    @Override
    @Transactional
    public DbmsView addOrUpdateDbmsView(DbmsView dbmsView) {
        DbmsView dbmsViewOld=queryDbmsView(dbmsView.getSourceId(),dbmsView.getViewName());
        if(dbmsViewOld==null){
            this.save(dbmsView);
            return dbmsView;
        }else {
            dbmsViewOld.setTextContent(dbmsView.getTextContent());
            dbmsViewOld.setTextLength(dbmsView.getTextLength());
            dbmsViewOld.setUpdateTime(new Date());
            dbmsViewOld.setCreated(dbmsView.getCreated());
            dbmsViewOld.setLastDdlTime(dbmsView.getLastDdlTime());
            dbmsViewOld.setCollectSid(dbmsView.getCollectSid());
            this.updateById(dbmsViewOld);
            return dbmsViewOld;
        }

    }

    @Transactional
    public void checkAndDeleteDbmsView(Long sourceId,String collectSid){
        UpdateWrapper<DbmsView> updateWrapper=new UpdateWrapper<DbmsView>();
        updateWrapper.set("update_time",new Date());
        updateWrapper.set("del_flag",1);
        updateWrapper.eq("source_id",sourceId);
        updateWrapper.eq("del_flag",0);
        updateWrapper.ne("collect_sid",collectSid);
        this.update(updateWrapper);
    }

    @Override
    public CompareResultModel queryViewCompareContentResult(Long sourceId1,Long sourceId2,String viewName){
        DbmsView view1=queryDbmsView(sourceId1,viewName);
        DbmsView view2=queryDbmsView(sourceId2,viewName);
        return new CompareResultModel(view1==null?"":view1.getTextContent(),view2==null?"":view2.getTextContent());
    }

    @Override
    public List<CompareResultModel> compareView(Long sourceId1, Long sourceId2, String viewName, Integer diff){
        return dbmsViewMapper.queryAllViewCompareResult(sourceId1,sourceId2,viewName,diff);
    }
    @Override
    public void syncView(Long sourceId1,Long sourceId2,String viewName)throws  Exception{
        DbmsView view1=queryDbmsView(sourceId1,viewName);
        DbmsView view2=queryDbmsView(sourceId2,viewName);
        Assert.isTrue(view1==null,"待同步视图为空");
        if(view2!=null){
            view2.setTextLength(view1.getTextLength());
            view2.setTextContent(view1.getTextContent());
            this.updateById(view2);
        }
        DbmsDbsource dbmsDbsource = dbmsDbsourceService.getById(sourceId2);
        DbmsDbtype dbmsDbtype = dbmsDbtypeService.getById(dbmsDbsource.getTypeId());
        DbSource dbSource = (DbSource) Class.forName(dbmsDbtype.getSourceClass()).newInstance();
        dbSource.initSource(dbmsDbtype.getTypeCode(), dbmsDbsource.getUrl(), dbmsDbsource.getUserName(), dbmsDbsource.getPassword(), dbmsDbtype.getJdbcDriver());
        String sql="CREATE OR REPLACE VIEW "+viewName+" AS "+view1.getTextContent();
        SqlRunner.runUpdateSql(dbSource,sql);

    }


    public DbmsView queryDbmsView(Long sourceId,String viewName){
        QueryWrapper<DbmsView> queryWrapper = new QueryWrapper<DbmsView>();
        queryWrapper.eq("source_id", sourceId).eq("view_name", viewName).eq("del_flag",0);
        return this.getOne(queryWrapper);
    }

}
